<?php

if (!defined('CORE_PATH'))
    die('Access Denied');

class Site extends Model {

    // page manager
    private $componentManager = NULL;
    private $pageManager = NULL;
    private $articlesManager = NULL;
    private $eventsManager = NULL;
    private $linksManager = NULL;
    private $downloadsManager = NULL;
    private $themeManager = NULL;
    private $spotlightManager = NULL;
    private $galleryManager = NULL;
    private $themeFolder = NULL;
    private $themeFolderPath = NULL;
    private static $instance;
    protected $helpers = array('HTML');
    
    /**
     *
     * @var Theme
     */
    public $theme = NULL;
    public $component = NULL;

    function __construct($data = NULL) {
        parent::__construct($data, 'sites');
    }

    public static function getInstance() {
        if (!isset(self::$instance) && defined('SITE_ID')) {
            $className = get_class();
            self::$instance = new $className(SITE_ID);
        }

        return self::$instance;
    }

    /**
     *
     * @return PageManager
     */
    public function getPageManager() {
        if ($this->pageManager == NULL) {
            $this->pageManager = new PageManager();
        }

        return $this->pageManager;
    }

    /**
     *
     * @return ArticlesManager
     */
    public function getArticlesManager() {
        if ($this->articlesManager == NULL) {
            $this->articlesManager = new ArticlesManager();
        }

        return $this->articlesManager;
    }

    /**
     *
     * @return EventsManager 
     */
    public function getEventsManager() {
        if ($this->eventsManager == NULL) {
            $this->eventsManager = new EventsManager();
        }

        return $this->eventsManager;
    }

    /**
     *
     * @return LinksManager 
     */
    public function getLinksManager() {
        if ($this->linksManager == NULL) {
            $this->linksManager = new LinksManager();
        }

        return $this->linksManager;
    }

    /**
     *
     * @return DownloadsManager 
     */
    public function getDownloadsManager() {
        if ($this->downloadsManager == NULL) {
            $this->downloadsManager = new DownloadsManager();
        }

        return $this->downloadsManager;
    }

    /**
     *
     * @return ThemeManager
     */
    public function getThemeManager() {
        if ($this->themeManager == NULL) {
            $this->themeManager = new ThemeManager();
        }

        return $this->themeManager;
    }

    /**
     * Returns the URL to the view/theme loader page specified. The parameter specified
     * should be an existing view/theme loader file, else an error will be thrown
     *
     * @param string $pageType
     * @deprecated 
     * @return string
     */
    public function getPageURL($pageType = 'index') {
        return $this->url($pageType);
    }

    /**
     * 
     * @param type $pageType
     * @return string
     * @throws InvalidArgumentException
     * 
     */
    public function url($pageType) {
        // throw exception if $pageType is not properly specified
        if (!is_string($pageType) || trim($pageType) == '') {
            throw new InvalidArgumentException("The Page To Provide A Link For Was Not Specified Correctly");
        }

        // if an actual view file does not exist for the page, throw an error
        $file = kan_fix_path("../core/views/" . (($pageType == "home" || $pageType == "index") ? "index" : $pageType) . ".php");
        /* if( !file_exists($file) ) {
          throw new Exception("A View File Does Not Exist For The Specified Page");
          } */

        // if all is well build the url and present it
        $url = "../pages/" . ( ($pageType == "home" || $pageType == "index") ? "index" : $pageType) . ".php?siteid=" . $this->getSiteIdentifier();

        // if using SEF_URLS
        if (SEF_URLS) {
            $url = "../" . $this->getSiteIdentifier() . "/" . (($pageType == "home" || $pageType == "index") ? "" : $pageType);
        }

        // if in the CMS do not fix the URL, return as is
        if (defined("IN_CMS") && IN_CMS) {
            return $url;
        }

        return kan_fix_url($url);
    }

    public function getFeedURL() {
        return $this->getArticlesManager()->getArticlesFeedURL();
    }

    public function getArticles($start = 0, $limit = NULL, $options = NULL) {
        return $this->getArticlesManager()->getArticles($start, $limit, $options);
    }

    public function getEvents($start = 0, $limit = NULL) {
        return $this->getEventsManager()->getEvents($start, $limit);
    }

    public function getSpotlights($start = 0, $limit = NULL) {
        if ($this->spotlightManager == NULL) {
            $this->spotlightManager = new SpotlightManager();
        }

        return $this->spotlightManager->getSpotlights($start, $limit);
    }

    public function getLinks($start = 0, $limit = NULL) {
        return $this->getLinksManager()->getLinks($start, $limit);
    }

    /**
     * Returns an array of Pages based on the supplied options. This method
     * defers to the PageManager::getPages method
     * 
     * @param array $options
     * @return Page[] 
     */
    public function getPages($options = NULL) {
        return $this->getPageManager()->getPages($options);
    }

    /**
     * Returns a Page based on the ID, PageNameAlias or Path provided
     *
     * @param mixed $id
     * @return Page the page to be displayed
     */
    public function getPage($id) {
        return $this->getPageManager()->getPage($id);
    }

    /**
     * Returns the current Galleries for this site
     *
     * @param mixed $id
     * @return Page the page to be displayed
     */
    public function getGalleries($start = 0, $limit = NULL, $options = NULL) {
        if ($this->galleryManager == NULL)
            $this->galleryManager = new GalleryManager();

        return $this->galleryManager->getGalleries($start, $limit, $options);
    }

    /**
     * Returns the current Galleries for this site
     *
     * @param mixed $id
     * @return Page the page to be displayed
     */
    public function getDownloads($start = 0, $limit = NULL) {
        return $this->getDownloadsManager()->getDownloads($start, $limit);
    }

    /**
     * Renders the heirachy of pages as an HTML list
     *
     * @param string $class the name of the class to use for the HTML List
     * @param int $depth the depth of level of a tree to build
     * @param bool $includeHome includes the home link in the list
     */
    public function renderMenu($class = "nav", $depth = 2, $includeHome = true) {
        return $this->getPageManager()->getPagesAsHTMLList($class, $depth, $includeHome);
    }

    /**
     * Renders the contents of the specified component at the location where
     * this function is called
     * 
     * @param string $componentName 
     */
    public function renderComponent($componentName, $vars = NULL) {

        if ($this->componentManager == NULL) {
            $this->componentManager = new ComponentsManager();
        }

        // make the global site variable available in this context
        $site = $this;

        if ($this->componentManager->componentExists($componentName)) {
            $component = $this->componentManager->getComponent($componentName);
            $site->component = $component; // keep a reference in the component for reference for use in the component

            if (file_exists($component->getPath())) {
                $contents = file_get_contents($component->getPath());

                // if we have variable passed, we need to create them so they can be used
                // by the component
                if (isset($vars) && is_array($vars)) {
                    extract($vars);
                }

                ob_start(); // buffer the output so we do not truncate current processing
                eval("?> " . $contents); // evaluate the php code by first ending the current one
                $eval_buffer = ob_get_contents(); // obtain the result of the evaluation
                ob_end_clean(); // empty the buffer

                echo $eval_buffer;
            } else {
                
            }
        }
    }

    public function getID() {
        return $this->getData("id");
    }

    public function getSiteID() {
        return $this->getData("id");
    }

    public function getSiteIdentifier() {
        return $this->getData("SiteIdentifier");
    }

    public function getSiteDomain() {
        return $this->getData("SiteDomain");
    }

    public function getSiteName() {
        return $this->getData("SiteName");
    }

    public function getSiteDescription() {
        return $this->getData("SiteDescription");
    }

    public function getSiteSlogan() {
        return $this->getData("SiteSlogan");
    }

    public function getSiteKeywords() {
        return $this->getData("SiteKeywords");
    }

    public function getSiteEmail() {
        return $this->getData("SiteEmail");
    }

    public function getSiteAddress() {
        return $this->getData("SiteAddress");
    }

    public function getSitePhone() {
        return $this->getData("SitePhone");
    }

    /**
     * Returns an HTML string containing the basic information needed to build the head
     * content of a common KAN site, include Meta Data (Keywords, Description), CSS Links
     * and Favicon information
     * 
     * The method checks if the current page being viewed is a page, article or event and
     * loads the Description meta data accordingly.
     * 
     * @global Page $page
     * @global Article $article
     * @global Event $event
     * @return string 
     */
    public function getHTMLHeadData() {
        global $page, $article, $event;

        $description = $this->getSiteDescription();

        $ThemeCSSID = $this->getData('SiteThemeCSSID');
        $theme = $this->getTheme();

        $ThemeID = $this->getData('SiteThemeID');


        // if the current ThemeID is not empty then we can try to determine the template information
        if ($this->themeFolder == NULL) {
            if ($ThemeID != '') {

                // next we need to determine which theme / template is being used for the current site
                $theme = new Theme($ThemeID);

                // get the folder containing the template files
                $themeFolder = $theme->getData('ThemeFolder');
                $this->themeFolder = kan_fix_url($themeFolder);

                // sanity check for when the database rather contains an empty themeFolder value
                // if the the themeFolder is empty, then we need to use the default template css
                if ($themeFolder == '') {
                    $themeFolder = "../assets/themes/default/";
                    $styleSheet = kan_fix_url($themeFolder . 'css/default/default.css');
                    $this->themeStyleSheet = "<link href='$styleSheet' rel='stylesheet' type='text/css' />";
                } else {

                    // if all is well with the database data, then we can proceed
                    // with pulling information about the css to use for this site
                    $themeCSS = new ThemeCSS($ThemeCSSID);
                    $styleSheet = $themeCSS->getData('CSSURL');

                    if ($styleSheet == '') {
                        $styleSheet = $themeFolder . 'css/default/default.css';
                    }

                    // fix to use an absolute path
                    $styleSheet = str_replace('../assets/themes/', THEMES_URL, $styleSheet);

                    // assign it to site object for re-use
                    $this->themeStyleSheet = "<link href='$styleSheet' rel='stylesheet' type='text/css' />";
                }

                // $themeFolderPath creation
                $this->themeFolderPath = str_replace('../assets/themes/', THEMES_PATH, $themeFolder);

                // if we have valid theme folder path, replace the relative URL with an absolute reference
                $this->themeFolder = str_replace('../assets/themes/', THEMES_URL, $themeFolder);
            } else {
                // if the ThemeID is empty, then we'll just use the default template and css
                $themeFolder = THEMES_URL . "default/";
                $styleSheet = $themeFolder . 'css/default/default.css';
                $this->themeStyleSheet = "<link href='$styleSheet' rel='stylesheet' type='text/css' />";

                // $themeFolderPath creation
                $this->themeFolderPath = str_replace('../assets/themes/', THEMES_PATH, $themeFolder);

                // if we have valid theme folder path, replace the relative URL with an absolute reference
                $this->themeFolder = str_replace('../assets/themes/', THEMES_URL, $themeFolder);
            }
        }


        $content = "<meta name='generator' content='KAN CMS 1.0 - Open Source Content Management System' />\r\n";
        $content .= "<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />\r\n";
        $content .= "<meta name='description' content='" . $description . "' />\r\n";
        $content .= "<meta name='keywords' content='" . $this->getSiteKeywords() . "' />\r\n";
        $content .= '<link rel="alternate" type="application/rss+xml" title="' . $this->getSiteName() . " - Articles" . '" href="' . $this->getArticlesManager()->getArticlesFeedURL() . '" />';
        $content .= $this->favicon() . "\r\n";
        $content .= $this->themeStyleSheet . "\r\n";

        return $content;
    }

    /**
     * Generate the favourite icon link information for the themes. If the
     * file has not been specified, then we will fallback and load the default
     * KAN favourites icon
     */
    private function favicon() {
        $favicon = kan_fix_url($this->getData('SiteFavicon'));

        if (file_exists($favicon) && stristr($favicon, ".ico") == "") {

            $info = getimagesize($favicon);
            $mime_type = $info['mime'];
            $site->siteFavicon = "<link rel='shortcut icon' href='$favicon' type='$mime_type' />";
        } else if (file_exists($favicon)) {
            $site->siteFavicon = "<link rel='shortcut icon' href='$favicon' type='image/x-icon' />";
        } else {
            $site->siteFavicon = "<link rel='shortcut icon' href='../favicon.png' type='image/png' />";
        }

        return $site->siteFavicon;
    }

    /**
     * Returns a KAN formatted URL string pointing to the Home Page of the site
     * 
     * @return string
     */
    public function getHomePageURL() {

        $url = "../pages/index.php?siteid=" . $this->getSiteIdentifier();

        if (SEF_URLS) {
            $url = "../" . $this->getSiteIdentifier() . "/";
        }

        return defined("IN_CMS") && IN_CMS ? $url : kan_fix_url($url);
    }

    /**
     * Returns a preprocessed HTML string for the home page text
     * 
     * @deprecated since version 2.0
     * @return string
     */
    public function getHomePageText() {
        return kan_process_html($this->getData("SiteHomePageText"));
    }

    /**
     * Returns a preprocessed HTML string for the footer text
     * @deprecated since version 2.0
     * 
     * @return string
     */
    public function getFooterText() {
        return kan_process_html($this->getData("SiteFooterText"));
    }

    /**
     * Returns the path to the Site Logo
     * 
     * @return string
     */
    public function getSiteLogo() {
        return kan_fix_url($this->getData("SiteLogo"));
    }

    /**
     * Returns the Theme object for the site's current theme
     * 
     * @return Theme
     */
    public function getTheme() {
        if (isset($this->theme) && $this->theme != NULL) {
            return $this->theme;
        }

        $this->theme = $this->getThemeManager()->getTheme($this->getData('SiteThemeID'));

        if ($this->theme->getData('ThemeFolder') != '') {

            $config_file = $this->theme->path('config.php');
            $site = $this;

            if (file_exists($config_file)) {
                include_once($config_file);
            }
        }

        return $this->theme;
    }

    /**
     * Returns a bool representing the current active state of the site
     * @return bool
     */
    public function isActive() {
        return intval($this->getData('SiteActive')) == 1;
    }

    public function isDefault() {
        return $this->getData('SiteType') == "main";
    }

    public function script($path) {
        return $this->HTML->renderScript(SCRIPTS_URL, $path);
    }

    private function css($path) {
        return $this->HTML->renderCSS(SCRIPTS_URL, $path);
    }

}

?>
